package wineshop.domain.market;

import static wineshop.commons.Validator.check;

import java.io.Serializable;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Version;

import wineshop.commons.Time;
import wineshop.domain.general.Address;

/**
 * The persistent class for the seller database table.
 * 
 */
@Entity
public class Seller implements Serializable {
	private static final long serialVersionUID = 1L;

	@Id
	@SequenceGenerator(name = "seller_seq", sequenceName = "wineshop_seq", allocationSize = 1)
	@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seller_seq")
	long id;

	@Version
	Integer version;

	@ManyToOne
	@JoinColumn(name = "address")
	private Address address;

	private String name;

	Seller() {
	}

	public Seller(String name, Address address) {
		this.name = name;
		this.address = address;
	}

	public Address getAddress() {
		return this.address;
	}

	public void setAddress(Address address) {
		this.address = address;
	}

	public String getName() {
		return this.name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Item makeNewItem(Product product, String code, Integer price,
			Integer year) {
		Item item = new Item(product, code, this, year, price);
		item.setAvailable(false);
		return item;
	}

	public void changeAvailability(boolean available, Item wine) {
		checkIfItemCanBeManaged(wine);
		wine.setAvailable(available);
	}

	public Purchase sell(Item wine, Customer customer, Creditcard card,
			Address addressDelivery) {
		check(customer.getCreditCards().contains(card),
				"Credit card " + card.getCode() + " not owned by "
						+ customer.getUsername());
		checkIfItemCanBeManaged(wine);
		check(wine.isAvailable(), "Wine " + wine.getCode()
				+ " is not available");
		Purchase purchase = new Purchase(wine, Time.now(), customer, card,
				addressDelivery);
		wine.setAvailable(false);
		return purchase;
	}

	public void checkIfItemCanBeManaged(Item wine) {
		check(wine.getSeller().equals(this), "Wine " + wine.getCode()
				+ ", is not selled by " + getName());
		check(!wine.isSold(), "Wine " + wine.getCode() + " already sold");
	}

}